﻿using DBUtil.Attributes;
using NUnit.Framework;
using Shouldly;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test.MySql.JsonTests
{
    [TestFixture]
    internal class JsonUpdateEntity : TestBase
    {
        #region model
        [Table("t_person")]
        public class PersonEntity
        {
            [PrimaryKey]
            public int Id { get; set; }
            [JsonMap]
            public ExtDetail Ext { get; set; }
        }
        public class ExtDetail
        {
            public string Name { get; set; }
            public string Addr { get; set; }
        }

        [Table("t_person2")]
        public class PersonEntity2
        {
            [PrimaryKey]
            public int Id { get; set; }
            [JsonMap]
            public List<ExtDetail> Ext { get; set; }
        }
        #endregion

        [SetUp]
        public void SetUp()
        {
            DropTableIfExist("t_person");
            db.ExecuteSql("""
                create table t_person(id int auto_increment primary key,ext json)
                """);

            DropTableIfExist("t_person2");
            db.ExecuteSql("""
                create table t_person2(id int auto_increment primary key,ext json)
                """);
        }

        [Test]
        public void Test()
        {
            var update = db.Update<PersonEntity>().SetEntity([
                new PersonEntity{Id=1,Ext=new ExtDetail{Name="jack",Addr="天明路"}},
                new PersonEntity{Id=2,Ext=new ExtDetail{Name="tom"}},
                new PersonEntity{Id=3,Ext=new ExtDetail{Name="lisa"}},
                ]);
            var sql = update.ToSql();
            sql.ShouldBe("""
                update `t_person` set
                    `Ext` = case `Id`
                      when 1 then '{"Name":"jack","Addr":"天明路"}'
                      when 2 then '{"Name":"tom","Addr":null}'
                      when 3 then '{"Name":"lisa","Addr":null}' end
                where `Id` in (1,2,3);
                """);

            update = db.Update<PersonEntity>().SetEntity([
                new PersonEntity{Id=1,Ext=new ExtDetail{Name="jack",Addr="天明路"}},
                new PersonEntity{Id=2,Ext=new ExtDetail{Name="tom"}},
                new PersonEntity{Id=3,Ext=new ExtDetail{Name="lisa"}},
                ]).SetColumn(i => i.Ext, new ExtDetail { Name = "demo" });
            sql = update.ToSql();
            sql.ShouldBe("""
                update `t_person` set
                    `Ext` = '{"Name":"demo","Addr":null}'
                where `Id` in (1,2,3);
                """);

            update = db.Update<PersonEntity>().SetEntity([
                new PersonEntity{Id=1,Ext=new ExtDetail{Name="jack",Addr="天明路"}},
                new PersonEntity{Id=2,Ext=new ExtDetail{Name="tom"}},
                new PersonEntity{Id=3,Ext= null},
                ]).SetColumn(i => i.Ext.Name, "ok");
            sql = update.ToSql();
            sql.ShouldBe("""
                update `t_person` set
                    `Ext` = case `Id`
                      when 1 then json_set('{"Name":"jack","Addr":"天明路"}',
                        '$."Name"','ok')
                      when 2 then json_set('{"Name":"tom","Addr":null}',
                        '$."Name"','ok')
                      when 3 then json_set(json_object(),
                        '$."Name"','ok') end
                where `Id` in (1,2,3);
                """);
        }

        [Test]
        public void Test2()
        {
            var update = db.Update<PersonEntity2>().SetEntity([
                new PersonEntity2{Id=1,Ext=[new ExtDetail{Name="jack",Addr="天明路"}] },
                new PersonEntity2{Id=2,Ext=[new ExtDetail{Name="tom"}] },
                new PersonEntity2{Id=3,Ext=[new ExtDetail{Name="lisa"}] },
                ]);
            var sql = update.ToSql();
            sql.ShouldBe("""
                update `t_person2` set
                    `Ext` = case `Id`
                      when 1 then '[{"Name":"jack","Addr":"天明路"}]'
                      when 2 then '[{"Name":"tom","Addr":null}]'
                      when 3 then '[{"Name":"lisa","Addr":null}]' end
                where `Id` in (1,2,3);
                """);
        }
    }
}
